#include "algorithm.h"

/** Vypise vysledek predaneho prirazeni.
 * \param calls prirazeni frekvenci, pokud je prazdne, pouzije se aktualni prirazeni v mape (atribut area->calls)
 */
void Algorithm::Print(int * calls) {
	if (calls == 0) calls = area->calls;
	general->Log() << "=========> RESULT: (frequencies = " << Frequencies() << "):" << std::endl;
	for (int i = 0; i < area->CELLS_CNT; ++i) {
		general->Log() << "| " << (i + 1) << " ||";
		int m = area->cells[i].index + area->cells[i].demand;
		for (int j = area->cells[i].index; j < m; ++j) {
			general->Log() << " " << calls[j];
		}
		general->Log() << std::endl;
	}
}

/** Vypise predane reseni do XML streamu.
 * \param out vystupni soubor (respektive stream)
 * \param calls prirazeni frekvenci, pokud je prazdne, pouzije se aktualni prirazeni v mape (atribut area->calls)
 */
void Algorithm::Print(std::ostream & out, int * calls) {
	if (calls == 0) calls = area->calls;
	out << "		<result>"<< Frequencies() << "</result>" << std::endl << "		<assignment>" << std::endl;
	for (int i = 0; i < area->CELLS_CNT; ++i) {
		out << "			<antena id=\"" << (i + 1) << "\">";
		int m = area->cells[i].index + area->cells[i].demand;
		for (int j = area->cells[i].index; j < m; ++j) {
			out << " " << calls[j];
		}
		out << "</antena>" << std::endl;
	}
	out << "		</assignment>" << std::endl;
	Print(calls);
}

/** Vypise aktualni reseni do XML streamu.
 * \param out vystupni soubor (respektive stream)
 */
void Algorithm::PrintResult(std::ostream & out) {
	Print(out, area->sortedCalls());
}

/** Zkontroluje spravnost aktualniho prirazeni.
 * \return true pokud je prirazeni spravne
 */
bool Algorithm::Correct() {
	int res = area->isAssignmentCorrect(frequencies);
	if (res == 0) return true;
	if (res > 0) general->Log() << "ERROR in assignment: " << res << " antenas with unassigned frequencies" << std::endl;
	else if (res == -1) general->Log() << "ERROR in assignment: corrupted constraint" << std::endl;
	else if (res == -2) general->Log() << "ERROR in assignment: frequency higher than frequency count" << std::endl;
	return false;
}

/** Vrati nahodne cislo v zadanem intervalu.
 * \param range rozsah hodnot nahodneho cisla
 * \param min nejmensi mozna hodnota nahodneho cisla
 * \return hodnota v rozsahu [min, min + range)
 */
int Algorithm::RandomNumber(int range, int min) {
	return (rand() % range) + min;
}
